"""
Author        yongfa
Date          2023-09-07 03:32:46
LastEditTime  2023-09-08 07:21:45
LastEditors   yongfa
Description   简历解析任务
"""

import time
import random

from flask import current_app

from app.extensions import celery_app, db
from app.modules.v1.resume.models import ResumeParserTask, ResumeContent
from app.extensions.utils import md5sum
from app.extensions.utils.enums import ResumeEmailParserStatusEnum

from app.app_celery import logger


@celery_app.task(bind=True, name='HandleResumeParser', routing_key='ResumeParser', priority=1)
def HandleResumeParser(self, resume_parser_task_id: int):
    """处理简历解析"""
    try:
        logger.info('HandleResumeParser: {}'.format(resume_parser_task_id))
        resume_parser_task = None
        count = 3
        while resume_parser_task is None and count > 0:
            resume_parser_task = ResumeParserTask.get_for_update(id=resume_parser_task_id)
            time.sleep(random.random())
            count -= 1

        if resume_parser_task is None:
            logger.info('resume_parser_task: {} 不存在'.format(resume_parser_task_id))
            return

        content = resume_parser_task.resume_text

        # TODO 调用解析接口
        code = md5sum(content)
        _resume_content = {
            "parser_text": content,
            "source_text": content,
            "code": code
        }
        resume_content = ResumeContent.get(code=code)
        if resume_content:
            resume_content.update(**_resume_content, commit=False)
        else:
            resume_content = ResumeContent.create(**_resume_content, commit=False)
            resume_content.flush()

        # 更新简历内容结果
        resume_parser_task.update(
            parser_status=ResumeEmailParserStatusEnum.PARSED.value,
            parser_message='解析完成',
            parser_times=1,
            resume_content_id=resume_content.id
        )

        callback_url = resume_parser_task.callback_url
        if callback_url:
            if current_app.config.get('CELERY_DEBUG_MODEL'):
                HandleResumeResultCallBack(resume_parser_task_id)
            else:
                HandleResumeResultCallBack.apply_async(args=(resume_parser_task_id,))

        return resume_content.to_dict()

    except Exception as exc:
        db.session.rollback()
        logger.exception("解析简历内容失败 resume_parser_task_id: {}  retries: {} error: {}".format(
            resume_parser_task_id, self.request.retries, str(exc)))
        raise self.retry(countdown=5, max_retries=3, exc=exc)  # 下次重试5s以后，最多重试3次


@celery_app.task(bind=True, name='HandleResumeResultCallBack', routing_key='ResumeResultCallBack', priority=0)
def HandleResumeResultCallBack(self, resume_parser_task_id: int):
    """处理简历结果回调"""
    try:
        logger.info('HandleResumeResultCallBack: {}'.format(resume_parser_task_id))
        resume_parser_task = ResumeParserTask.get_for_update(id=resume_parser_task_id)
        resume_content = None
        count = 3
        while resume_content is None and count > 0:
            resume_content = ResumeContent.get(id=resume_parser_task.resume_content_id)
            time.sleep(random.random())
            count -= 1

        callback_status = 0
        _resume_parser_task = {
            'callback_status': callback_status,
            'callback_times': self.request.retries + 1
        }
        # 回调次数超过3次,记录失败，结束回调任务
        if self.request.retries == 3:
            logger.info("resume_parser_task: {} 回调次数超过3次".format(resume_parser_task_id))
            resume_parser_task.update(**_resume_parser_task)
            return

        callback_url = resume_parser_task.callback_url

        if not callback_url:
            logger.info("resume_parser_task: {} 没有回调地址".format(resume_parser_task_id))
            resume_parser_task.update(**_resume_parser_task)
        else:
            logger.info("resume_parser_task: {} 回调地址: {}".format(resume_parser_task_id, callback_url))

            # TODO 加密简历内容并回调结果
            logger.info("resume_parser_task: {} 回调成功！".format(resume_parser_task_id))
            callback_status = 1
            _resume_parser_task = {
                'callback_status': callback_status,
                'callback_times': self.request.retries + 1
            }
            resume_parser_task.update(**_resume_parser_task)

    except Exception as exc:
        db.session.rollback()
        logger.exception("回调简历内容失败 resume_parser_task_id: {}  retries: {} error: {}".format(
            resume_parser_task_id, self.request.retries, str(exc)))
        raise self.retry(countdown=5, max_retries=3, exc=exc)  # 下次重试5s以后，最多重试3次
